#!groovy
@Library("jenkinslib") _

//func from sharelibrary调用共享库
def build=new org.devops.build()
def k8s=new org.devops.k8s()
def k8sdeploy=new org.devops.k8sdeploy()
def tools=new org.devops.tools()
def harbor=new org.devops.Harbor()
def toemail=new org.devops.toemail()
//调用Jenkins中定义的选项参数 名称和Jenkins中定义的保持一致
//from jenkins 参数化构建变量
String Tenv="${env.Tenv}"
String buildType="${env.buildType}"
String buildshell="${env.buildshell}"
String deployHosts="${env.deployHosts}"
String srcURL="${env.SrcURL}"
String branch="${env.branchName}"
String k8s_ns="${env.k8s_ns}"
String controllerType="${env.controllerType}"
String imageName="${env.imageName}"
String imageTag="${env.imageTag}" 
String replicas="${env.replicas}"
String containerPort="${env.ContainerPort}"
Boolean rollback = (env.rollback == 'true')

// 固定配置
env.HARBOR_URL = "harbor.jdicity.local"
env.PROJECT_GROUP = "registry"

pipeline{
    agent {
        kubernetes { 
            cloud 'kubernetes'              // 对应 Jenkins 中配置的 Kubernetes 云名称
            inheritFrom 'jenkins-slave'  // 继承的 Pod 模板（可选）
            namespace 'default'      // 命名空间
            yaml k8s()            // 调用共享库生成 Pod YAML
        }
    }
    options {
        timestamps()
        skipDefaultCheckout()  // 禁用隐式 Checkout
        timeout(time: 1, unit: 'HOURS') //设置流水线超时
    }
    stages{
        stage("CheckOut"){
            when { expression { !rollback } }  // 非回滚时执行
            steps{
                script{
                    tools.PrintMsg("获取分支: ${branch}","checkout")
                    tools.PrintMsg("获取代码","checkout")
                    checkout([$class: 'GitSCM', branches: [[name: "${branch}"]], 
                        extensions: [], 
                        userRemoteConfigs: [[credentialsId: 'gitee_registry_ssh', url: "${srcURL}"]]])
                }
            }
        }
        stage("Build"){
            when { expression { !rollback } }  // 非回滚时执行
            steps{
                script{
                    //集成构建工具
                    container('mvn') {
                        tools.PrintMsg("代码打包","build")
                        build.Build(buildType,buildshell)
                    }
                }
            }
        }
        stage("镜像tag"){
            when { expression { !rollback } }  // 非回滚时执行
            steps{
                script{
                    tools.PrintMsg("获取镜像tag","image_tag")
                    // 使用 Jenkins 主机的本地时间（绕过容器时钟问题）
                    TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"))
                    env.BUILD_TIME = new Date().format("yyyyMMdd_HHmmss")
                        // 组合完整Tag
                    env.FULL_IMAGE_TAG = "${imageTag}"+"_"+env.BUILD_TIME
                    env.FULL_IMAGE_NAME="${env.HARBOR_URL}/${env.PROJECT_GROUP}/${imageName}:${env.FULL_IMAGE_TAG}"
                    tools.PrintMsg("生成镜像Tag: ${FULL_IMAGE_TAG}", "image_tag")
                    tools.PrintMsg("生成镜像地址: ${FULL_IMAGE_NAME}", "image_tag")
                   
                }    
            }
        }
        stage("镜像构建"){
            when { expression { !rollback } }  // 非回滚时执行
            steps{
                script{
                    container('docker') {
                        tools.PrintMsg("代码打包","image_build")
                        harbor.BuildImage(
                        this,
                        'HARBOR_ID',
                        env.HARBOR_URL,
                        env.PROJECT_GROUP,
                        "${imageName}",
                        env.FULL_IMAGE_TAG)
                    }
                }
            }
        }
        stage("生成部署模板") {
            when { expression { !rollback } }
            steps {
                container('kubectl') {
                    script {
                        tools.PrintMsg("并行生成部署模板","template")
                                // 根据资源类型选择模板
                        def templateFile = ("${controllerType}".toLowerCase() == 'statefulset') ? 
                            'statefulset-template.yaml' : 'deployment-template.yaml'
                        // 并行生成不同类型的模板
                        parallel(
                            "生成${controllerType}模板": {
                                // 读取模板内容
                                String template = readFile("${templateFile}")
                                
                                // 定义替换变量
                                def replacements = [
                                    '${imageName}'       : "${imageName}",
                                    '${replicas}'       : "${replicas}",
                                    '${FULL_IMAGE_NAME}': env.FULL_IMAGE_NAME,
                                    '${containerPort}'   : "${containerPort}",
                                    '${k8s_ns}'         : "${k8s_ns}"
                                ]
                                
                                // 执行替换并写入文件
                                String yamlContent = replacements.inject(template) { 
                                    content, entry -> content.replace(entry.key, entry.value) 
                                }
                                writeFile file: "${WORKSPACE}/${controllerType}.yaml", text: yamlContent
                            },
                            
                            "生成Service模板": {
                                // 读取模板内容
                                String templatesvc = readFile('svc-template.yaml')
                                
                                // 定义替换变量
                                def replacements = [
                                    '${imageName}'    : "${imageName}",
                                    '${containerPort}': "${containerPort}",
                                    '${k8s_ns}'       : "${k8s_ns}"
                                ]
                                
                                // 执行替换并写入文件
                                String svcYaml = replacements.inject(templatesvc) { 
                                    content, entry -> content.replace(entry.key, entry.value) 
                                }
                                writeFile file: "${WORKSPACE}/svc.yaml", text: svcYaml
                            },
                            
                            failFast: true  // 任一失败则立即终止
                        )
                    }
                }
            }
        }
        stage("部署到k8s"){
            when { expression { !rollback } }  // 非回滚时执行
            steps{
                script{
                    container('kubectl') {
                        tools.PrintMsg("部署到${Tenv}环境","deploy")
                        k8sdeploy.Deploy(
                        this,
                        "${Tenv}",
                        "${controllerType}",
                        "${imageName}",
                        "${env.FULL_IMAGE_NAME}",
                        "${k8s_ns}"
                        )
                        // 在发布阶段将镜像名称保存到 env.FULL_IMAGE_NAME
                        env.FULL_IMAGE_NAME = "${env.FULL_IMAGE_NAME}"
                        currentBuild.description = "${env.FULL_IMAGE_NAME}"
                    }
                }
            }
        }
        stage("是否回滚"){
            when { expression { rollback } }  // 回滚时执行
            steps{
                script{
                    container('kubectl') {
                        tools.PrintMsg("回滚到${Tenv}环境","rollback")
                        def  rollbackImage = k8sdeploy.Rollback(
                            this,
                            "${Tenv}",
                            "${controllerType}",
                            // 'k8s',
                            "${imageName}",
                            "${k8s_ns}"
                        )
                        // 保存回滚镜像信息
                        env.FULL_IMAGE_NAME = rollbackImage  // 使用回滚镜像替换 FULL_IMAGE_NAME
                        // 保存回滚镜像信息
                        currentBuild.description = "${rollbackImage}"
                    }
                }
            }
        }
    }
    post {
        always {
            script {
                // 获取构建时间和持续时间
                TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"))
                env.BUILD_TIME = new Date().format("yyyyMMdd_HHmmss")
                def buildTime = env.BUILD_TIME ?: "N/A"
                def buildDuration = currentBuild.durationString ?: "N/A"
                // 发送邮件
                toemail.Email(
                    currentBuild.currentResult,
                    "${env.emailUser}",
                    "${imageName}",
                    "${branch}",
                    "${env.BUILD_USER}",
                    buildTime,
                    buildDuration,
                    rollback,
                    "${k8s_ns}",
                    currentBuild.description,
                    "${srcURL}"
                )
            }
        }
    }
}